package com.dingteam.question.common.validation.module;

import com.dingteam.model.Result;
import com.dingteam.question.common.domain.QuestionItemOption;
import com.dingteam.question.common.dto.QuestionPaperVerifyDTO;
import com.dingteam.question.common.dto.QuestionResultVerifyDTO;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;

import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 选项组件
 * @author Jamin
 * @date 2019/08/14
 */
public abstract class AbstractModuleOptionValidator implements ModuleValidator {

	protected Result<String> validCreateIndefinite(QuestionPaperVerifyDTO.QuestionItemDTO itemDTO) {
		if (Objects.isNull(itemDTO.getMulti())) {
			return Result.error("{validation.item.multi.null.message}", EMPTY);
		}
		if (Objects.equals(true, itemDTO.getMulti())) {
			return validCreateCheckbox(itemDTO);
		} else {
			return validCreateRadio(itemDTO);
		}
	}

	protected Result<String> validSubmitIndefinite(QuestionResultVerifyDTO.ItemResultDTO item) {
		if (Objects.equals(true, item.getQuestionItem().getMulti())) {
			return validSubmitCheckbox(item);
		} else {
			return validSubmitRadio(item);
		}
	}

	protected Result<String> validCreateCheckbox(QuestionPaperVerifyDTO.QuestionItemDTO itemDTO) {
		Result<String> result = validCreateCommon(itemDTO);
		if (!result.getSuccess()) {
			return result;
		}
		if (Objects.isNull(itemDTO.getMax())) {
			return Result.error("{validation.item.max.null.message}", EMPTY);
		}
		if (Objects.isNull(itemDTO.getMin())) {
			return Result.error("{validation.item.min.null.message}", EMPTY);
		}
		if (itemDTO.getMin() > itemDTO.getMax()) {
			return Result.error("{validation.item.min.illegal.message}", EMPTY);
		}
		Result<String> option = validCreateOption(itemDTO);
		if (!option.getSuccess()) {
			return option;
		}
		if (itemDTO.getMax() > itemDTO.getOptions().size()) {
			return Result.error("{validation.item.max.illegal.message}", EMPTY);
		}
		return Result.ok().build();
	}

	protected Result<String> validCreateRadio(QuestionPaperVerifyDTO.QuestionItemDTO itemDTO) {
		Result<String> result = validCreateCommon(itemDTO);
		if (!result.getSuccess()) {
			return result;
		}
		return validCreateOption(itemDTO);
	}

	private Result<String> validCreateCommon(QuestionPaperVerifyDTO.QuestionItemDTO itemDTO) {
		if (Objects.isNull(itemDTO.getRandomOrder())) {
			return Result.error("{validation.item.randomOrder.null.message}", EMPTY);
		}
		if (Objects.isNull(itemDTO.getRequired())) {
			return Result.error("{validation.item.required.null.message}", EMPTY);
		}
		return Result.ok().build();
	}

	private Result<String> validCreateOption(QuestionPaperVerifyDTO.QuestionItemDTO itemDTO) {
		List<QuestionPaperVerifyDTO.QuestionItemOptionDTO> options = itemDTO.getOptions();
		if (CollectionUtils.isEmpty(options)) {
			return Result.error("{validation.item.options.empty.message}", EMPTY);
		}
		for (QuestionPaperVerifyDTO.QuestionItemOptionDTO itemOption : options) {
			if (StringUtils.isBlank(itemOption.getText())) {
				return Result.error("{validation.itemOption.text.blank.message}", EMPTY);
			}
		}
		return Result.ok().build();
	}

	protected Result<String> validSubmitCheckbox(QuestionResultVerifyDTO.ItemResultDTO item) {
		Result<String> result = validSubmitCommon(item);
		if (!result.getSuccess()) {
			return result;
		}
		List<QuestionResultVerifyDTO.OptionResultDTO> options = item.getOptions();
		if (CollectionUtils.isNotEmpty(options)) {
			Integer max = item.getQuestionItem().getMax();
			Integer min = item.getQuestionItem().getMin();
			if (options.size() < min || options.size() > max) {
				return Result.error("{validation.multi.option.num.illegal.message}", EMPTY);
			}
		}
		return result;
	}

	protected Result<String> validSubmitRadio(QuestionResultVerifyDTO.ItemResultDTO item) {
		Result<String> result = validSubmitCommon(item);
		if (!result.getSuccess()) {
			return result;
		}
		List<QuestionResultVerifyDTO.OptionResultDTO> options = item.getOptions();
		if (CollectionUtils.isNotEmpty(options) && options.size() != 1) {
			return Result.error("{validation.radio.option.must.one.message}", EMPTY);
		}
		return result;
	}

	private Result<String> validSubmitCommon(QuestionResultVerifyDTO.ItemResultDTO item) {
		if (Boolean.TRUE.equals(item.getQuestionItem().getRequired())) {
			if (CollectionUtils.isEmpty(item.getOptions())) {
				return Result.error("{validation.required.option.not.empty.message}", EMPTY);
			}
		}
		List<QuestionItemOption> itemOptions = item.getQuestionItem().getItemOptions();
		if (CollectionUtils.isNotEmpty(itemOptions)) {
			Map<String, QuestionItemOption> optionMap = itemOptions
				.stream()
				.collect(Collectors.toMap(QuestionItemOption::getId, Function.identity(), (k1, k2) -> k1));
			List<QuestionResultVerifyDTO.OptionResultDTO> options = item.getOptions();
			if (CollectionUtils.isNotEmpty(options)) {
				options.removeIf(o -> {
					QuestionItemOption option = optionMap.get(o.getOptionId());
					o.setItemOption(option);
					return Objects.isNull(option);
				});
			}
		}
		return Result.ok().build();
	}

}
